- name: d8.istio.dataplane
  rules:
  - alert: D8IstioActualVersionIsNotInstalled
    annotations:
      description: |
        There are pods with injected sidecar with version `{{$labels.version}}` (revision `{{$labels.revision}}`) in namespace `{{$labels.namespace}}`, but the control-plane version isn't installed. Consider installing it or change the Namespace or Pod configuration.
        Impact — Pods have lost their sync with k8s state.
        Getting orphaned pods:
        ```
        kubectl -n {{ $labels.namespace }} get pods -l 'service.istio.io/canonical-name' -o json | jq --arg revision {{ $labels.revision }} '.items[] | select(.metadata.annotations."sidecar.istio.io/status" // "{}" | fromjson | .revision == $revision) | .metadata.name'
        ```
      plk_create_group_if_not_exists__d8_istio_dataplane_misconfigurations: D8IstioDataplaneMisconfigurations,tier=~tier,prometheus=deckhouse,kubernetes=~kubernetes
      plk_grouped_by__d8_istio_dataplane_misconfigurations: D8IstioDataplaneMisconfigurations,tier=~tier,prometheus=deckhouse,kubernetes=~kubernetes
      plk_markup_format: markdown
      plk_protocol_version: "1"
      summary: control-plane version for Pod with already injected sidecar isn't installed
    expr: |
      (
        max by (dataplane_pod, namespace, revision, desired_revision, version, desired_version)
        (
          d8_istio_dataplane_metadata{ revision!="absent" }
          unless on (revision)
          (
            istio_build{ component="pilot" }
            * on (pod,namespace) group_left(revision)
            (
              label_replace(kube_pod_labels, "revision", "$1", "label_istio_io_rev", "(.+)")
            )
          )
        )
      # labels kube-state-metrics should exist
      ) and on() count( up{ job="kube-state-metrics", scrape_endpoint="main" } == 1 ) > 0
    for: 5m
    labels:
      severity_level: "4"
      tier: cluster
  - alert: D8IstioDesiredVersionIsNotInstalled
    annotations:
      description: |
        There is desired istio control plane version `{{$labels.desired_version}}` (revision `{{$labels.revision}}`) configured for pods in namespace `{{$labels.namespace}}`, but the version isn't installed. Consider installing it or change the Namespace or Pod configuration.
        Impact — Pods won't be able to re-create in the `{{$labels.namespace}}` Namespace.
        Cheat sheet:
        ```
        ### namespace-wide configuration
        # istio.io/rev=vXYZ — use specific revision
        # istio-injection=enabled — use global revision
        kubectl get ns {{$labels.namespace}} --show-labels

        ### pod-wide configuration
        kubectl -n {{$labels.namespace}} get pods -l istio.io/rev={{$labels.revision}}
        ```
      plk_create_group_if_not_exists__d8_istio_dataplane_misconfigurations: D8IstioDataplaneMisconfigurations,tier=~tier,prometheus=deckhouse,kubernetes=~kubernetes
      plk_grouped_by__d8_istio_dataplane_misconfigurations: D8IstioDataplaneMisconfigurations,tier=~tier,prometheus=deckhouse,kubernetes=~kubernetes
      plk_markup_format: markdown
      plk_protocol_version: "1"
      summary: Desired control-plane version isn't installed
    expr: |
      (
        max by (dataplane_pod, namespace, revision, version, desired_version)
        (
          label_replace( d8_istio_dataplane_metadata{ desired_revision!="absent" }, "revision", "$1", "desired_revision", "(.+)" )
          unless on (revision)
          (
            istio_build{ component="pilot" }
            * on (pod,namespace) group_left(revision)
            (
              label_replace(kube_pod_labels, "revision", "$1", "label_istio_io_rev", "(.+)")
            )
          )
        )
      # labels kube-state-metrics should exist
      ) and on() count( up{ job="kube-state-metrics", scrape_endpoint="main" } == 1 ) > 0
    for: 5m
    labels:
      severity_level: "6"
      tier: cluster
  - alert: D8IstioDataPlaneWithoutIstioInjectionConfigured
    annotations:
      description: |
        There are Pods in `{{$labels.namespace}}` Namespace with istio sidecars, but the istio-injection isn't configured.
        Impact — Pods will lose their istio sidecars after re-creation.
        Getting affected Pods:
        ```
        kubectl -n {{$labels.namespace}} get pods -o json | jq -r --arg revision {{$labels.revision}} '.items[] | select(.metadata.annotations."sidecar.istio.io/status" // "{}" | fromjson | .revision == $revision) | .metadata.name'
        ```
      plk_create_group_if_not_exists__d8_istio_dataplane_misconfigurations: D8IstioDataplaneMisconfigurations,tier=~tier,prometheus=deckhouse,kubernetes=~kubernetes
      plk_grouped_by__d8_istio_dataplane_misconfigurations: D8IstioDataplaneMisconfigurations,tier=~tier,prometheus=deckhouse,kubernetes=~kubernetes
      plk_markup_format: markdown
      plk_protocol_version: "1"
      summary: There are Pods with istio sidecars, but without istio-injection configured
    expr: |
      max by (dataplane_pod, namespace, revision, desired_revision, version, desired_version)
        (
           d8_istio_dataplane_metadata{desired_revision="absent",revision!="absent"}
        )
    for: 5m
    labels:
      severity_level: "4"
      tier: cluster
  - alert: D8IstioPodsWithoutIstioSidecar
    annotations:
      description: |
        There is a Pod `{{$labels.dataplane_pod}}` in `{{$labels.namespace}}` Namespace without istio sidecars, but the istio-injection is configured.
        Getting affected Pods:
        ```
        kubectl -n {{$labels.namespace}} get pods -l '!service.istio.io/canonical-name' -o json | jq -r '.items[] | select(.metadata.annotations."sidecar.istio.io/inject" != "false") | .metadata.name'
        ```
      plk_create_group_if_not_exists__d8_istio_dataplane_misconfigurations: D8IstioDataplaneMisconfigurations,tier=~tier,prometheus=deckhouse,kubernetes=~kubernetes
      plk_grouped_by__d8_istio_dataplane_misconfigurations: D8IstioDataplaneMisconfigurations,tier=~tier,prometheus=deckhouse,kubernetes=~kubernetes
      plk_markup_format: markdown
      plk_protocol_version: "1"
      summary: There are Pods without istio sidecars, but with istio-injection configured
    expr: |
      max by (dataplane_pod, namespace, revision, desired_revision, version, desired_version)
        (
           d8_istio_dataplane_metadata{revision="absent", desired_revision!=""}
        )
    for: 5m
    labels:
      severity_level: "4"
      tier: cluster
  - alert: D8IstioActualDataPlaneVersionNeDesired
    annotations:
      description: |
        There are Pods in Namespace `{{$labels.namespace}}` with istio data-plane version `{{$labels.version}}`, but the desired one is `{{$labels.desired_version}}`.
        Impact — istio version is to change after Pod restarting.
        Cheat sheet:
        ```
        ### namespace-wide configuration
        # istio.io/rev=vXYZ — use specific revision
        # istio-injection=enabled — use global revision
        kubectl get ns {{$labels.namespace}} --show-labels

        ### pod-wide configuration
        kubectl -n {{$labels.namespace}} get pods -l istio.io/rev={{$labels.desired_revision}}
        ```
      plk_create_group_if_not_exists__d8_istio_dataplane_misconfigurations: D8IstioDataplaneMisconfigurations,tier=~tier,prometheus=deckhouse,kubernetes=~kubernetes
      plk_grouped_by__d8_istio_dataplane_misconfigurations: D8IstioDataplaneMisconfigurations,tier=~tier,prometheus=deckhouse,kubernetes=~kubernetes
      plk_markup_format: markdown
      plk_protocol_version: "1"
      summary:
        There are Pods with istio data-plane version `{{$labels.version}}`,
        but desired version is `{{$labels.desired_version}}`
    expr: |
      max by (dataplane_pod, namespace, revision, desired_revision, version, desired_version)
      (
        d8_istio_dataplane_metadata{revision!="absent", desired_revision!="absent"}
      )
      unless on (revision, dataplane_pod, namespace) label_replace(d8_istio_dataplane_metadata{}, "revision", "$1", "desired_revision", "(.+)")
    for: 5m
    labels:
      severity_level: "8"
      tier: cluster
  - alert: D8IstioDataPlaneVersionMismatch
    annotations:
      description: |
        There are Pods in `{{$labels.namespace}}` namespace with istio data-plane version `{{$labels.full_version}}` which differ from control-plane one `{{$labels.desired_full_version}}`.
        Consider restarting affected Pods, use PromQL query to get the list:
        ```
        max by (namespace, dataplane_pod) (d8_istio_dataplane_metadata{full_version="{{$labels.full_version}}"})
        ```
        Also consider using the automatic istio data-plane update described in the documentation: https://deckhouse.io/documentation/v1/modules/110-istio/examples.html#upgrading-istio
      plk_create_group_if_not_exists__d8_istio_dataplane_misconfigurations: D8IstioDataplaneMisconfigurations,tier=~tier,prometheus=deckhouse,kubernetes=~kubernetes
      plk_grouped_by__d8_istio_dataplane_misconfigurations: D8IstioDataplaneMisconfigurations,tier=~tier,prometheus=deckhouse,kubernetes=~kubernetes
      plk_markup_format: markdown
      plk_protocol_version: "1"
      summary:
        There are Pods with data-plane version different from control-plane
        one.
    expr: |
      max by (dataplane_pod, namespace, full_version, desired_full_version)
      (
        (
          d8_istio_dataplane_metadata{full_version!~"(unknown|absent)", desired_full_version!="absent"}
          # ignore pods with different revisions
          * on (namespace, dataplane_pod, full_version, desired_full_version, revision) label_replace(d8_istio_dataplane_metadata{}, "revision", "$1", "desired_revision", "(.+)")
        )
        unless on (full_version, dataplane_pod, namespace) label_replace(d8_istio_dataplane_metadata{}, "full_version", "$1", "desired_full_version", "(.+)")
      )
    for: 5m
    labels:
      severity_level: "8"
      tier: cluster
